package com.hksj.gas.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hksj.cbm.service.DeviceInstanceService;
import com.hksj.cbm.vo.SpaceModelVO;
import com.hksj.common.core.util.EasyExcelUtil;
import com.hksj.gas.dto.GasAlarmDTO;
import com.hksj.gas.mapper.GasAlarmMapper;
import com.hksj.gas.vo.ExportGasAlarmInfoVO;
import com.hksj.gas.vo.GasAlarmCountRankVO;
import com.hksj.gas.vo.GasAlarmListVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class GasAlarmService {

    @Autowired
    private GasAlarmMapper gasAlarmMapper;

    @Autowired
    private DeviceInstanceService deviceInstanceService;

    /**
     * 分页查询气体报警信息。
     * 通过气体报警DTO对象查询指定条件下的气体报警信息，并进行分页处理。
     * 如果查询结果包含路径信息，则将路径信息转换为UTF-8编码。
     *
     * @param dto 查询条件对象，包含分页信息和查询条件。
     * @return 返回分页查询结果，包含气体报警信息列表。
     */
    public IPage<GasAlarmListVO> queryDeviceAlarmByPage(GasAlarmDTO dto) {
        // 初始化分页对象
        IPage<GasAlarmListVO> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        // 根据查询条件和分页信息查询气体报警列表
        List<GasAlarmListVO> list = gasAlarmMapper.queryDeviceAlarmByPage(dto, page);
        // 如果查询结果为空，直接返回分页对象
        if (CollUtil.isEmpty(list)) {
            return page;
        }
        // 提取所有查询结果中的路径信息
        List<String> pathList = list.stream()
                .map(GasAlarmListVO::getPaths)
                .filter(Objects::nonNull) // 过滤掉空的路径信息
                .collect(Collectors.toList());
        // 如果路径信息为空，直接返回分页对象
        if (CollUtil.isEmpty(pathList)) {
            return page;
        }
        // 将路径信息转换为UTF-8编码，并映射到相应的气体报警对象上
        Map<String, List<SpaceModelVO>> pathNameMap = deviceInstanceService.devicePathConvertToUTF8(pathList);
        // 如果转换结果不为空，更新气体报警对象中的路径信息
        if (CollUtil.isNotEmpty(pathNameMap)) {
            list.forEach(alarmVO -> {
                alarmVO.setSpaceModelVOList(pathNameMap.get(alarmVO.getPaths()));
            });
        }
        // 设置分页对象的记录列表，返回处理后的分页查询结果
        page.setRecords(list);
        return page;
    }


    public List<GasAlarmCountRankVO> queryAlarmCountRank(GasAlarmDTO dto) {
        return gasAlarmMapper.queryAlarmCountRank(dto);
    }

    /**
     * 导出气体报警设备的历史报警信息。
     *
     * @param dto 分页查询参数，包含页码和每页大小。
     * @param response HTTP响应对象，用于将导出的文件发送给客户端。
     */
    public void exportAlarmDevice(GasAlarmDTO dto, HttpServletResponse response) {
        // 创建分页对象并设置页码和每页大小，但后续将页大小设置为-1，表示不分页查询
        IPage<GasAlarmListVO> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        //调用分页的方法获取不分页的数据。
        page.setSize(-1L);

        // 根据查询条件和分页信息查询气体报警设备的报警历史
        List<GasAlarmListVO> list = gasAlarmMapper.queryDeviceAlarmByPage(dto, page);

        List<ExportGasAlarmInfoVO> data = new ArrayList<>();
        if(!CollectionUtils.isEmpty(list)) {
            // 提取所有设备的空间模型路径
            List<String> pathList = list.stream()
                    .map(GasAlarmListVO::getPaths)
                    .filter(Objects::nonNull) // 这里添加了 filter 操作来移除 null 值
                    .collect(Collectors.toList());

            // 如果存在路径信息，转换路径信息为UTF-8编码，并映射到相应的设备报警信息上
            if (!CollectionUtils.isEmpty(pathList)) {
                Map<String, List<SpaceModelVO>> pathNameMap = deviceInstanceService.devicePathConvertToUTF8(pathList);
                if (!CollUtil.isEmpty(pathNameMap)) {
                    list.forEach(alarmVO -> {
                        alarmVO.setSpaceModelVOList(pathNameMap.get(alarmVO.getPaths()));
                    });
                }
            }

            // 将设备报警信息转换为导出格式的VO列表
            data = list.stream()
                    .map(vo -> {
                        ExportGasAlarmInfoVO excelVo = new ExportGasAlarmInfoVO();
                        excelVo.setAlarmTime(vo.getCreateTime());
                        excelVo.setDeviceName(vo.getDeviceName());
                        excelVo.setVal(vo.getValue());
                        // 拼接设备位置信息
                        if (!CollUtil.isEmpty(vo.getSpaceModelVOList())) {
                            String deviceLocation = vo.getSpaceModelVOList().stream()
                                    .map(SpaceModelVO::getModelName)
                                    .collect(Collectors.joining("->"));
                            excelVo.setDeviceLocation(deviceLocation);
                        }
                        return excelVo;
                    })
                    .collect(Collectors.toList());

            // 为导出的数据添加序列号
            int i = 1;
            for (ExportGasAlarmInfoVO vo : data) {
                vo.setSeq(i);
                i++;
            }
        }

        // 导出名称
        String fileName = new StringBuffer()
                .append("医用气体告警历史数据")
                .append(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"))
                .toString();

        // 使用EasyExcel工具类导出数据到响应对象
        EasyExcelUtil.exportExcelData(response,fileName,data,ExportGasAlarmInfoVO.class);
    }

}
